/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ru.staf.NetworkReportGenerator;

import java.io.IOException;
import org.jrobin.data.DataProcessor;
import java.util.Date;
import java.util.Set;
import java.util.HashSet;
import java.util.Iterator;
import java.util.HashMap;
import java.io.File;
import java.io.FileReader;
import java.io.LineNumberReader;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.ResultSet;
import org.jrobin.core.RrdException;

/**
 *
 * @author aezhov
 */
public class DeviceStatReader {
    String SQL_QUERY = "SELECT snmpifname, snmpifindex, snmpifdescr FROM snmpinterface where nodeid=";

    Date date1 = null;
    Date date2 = null;
    String fileSep = System.getProperty("file.separator");
    DataProcessor dp = null;
    HashMap<String, String> linkSpeeds = new HashMap<String, String>();
    HashMap<String, String> snmpPortMap = new HashMap<String,String>();
    HashMap<String, HashSet<String>> portMacMap = null;
    HashMap<String, HashSet<String>> portIpMap = null;
    HashMap<String, Boolean> upDownMap = null;

    public DeviceStatReader(Switch sw, Set portDirs, NmapXMLParser nmapParser, 
            Date date1, Date date2) throws org.jrobin.core.RrdException,
                                           java.io.IOException
    {
        String mainDir = sw.dir;

        // Getting map snmpporname -> snmpportid
        Connection dbConnect = sw.dbConnect;
        if (dbConnect != null) {
            try {
                SQL_QUERY += sw.OpenNMSid;
                System.out.println(SQL_QUERY);
                PreparedStatement stmt = dbConnect.prepareStatement(SQL_QUERY);
                ResultSet result = stmt.executeQuery();
                while (result.next()) {
                    String pName = result.getString(1);
                    int pId = result.getInt(2);
                    String ifDescr = result.getString(3);
                    ifDescr = ifDescr.replaceAll("[^A-Za-z0-9]", "_");

                    if (pName != null)
                        snmpPortMap.put(new Integer(pId).toString(), pName);
                    else
                        snmpPortMap.put(new Integer(pId).toString(), ifDescr);
                }
            } catch (java.sql.SQLException exc) {
                System.out.println("=== OpenNMS database connect problem " + exc);
            }

            //SnmpWalker snmp = new SnmpWalker(sw, snmpPortMap, nmapParser);
            FileSnmpWalker snmp = new FileSnmpWalker(sw, snmpPortMap, nmapParser);
            portMacMap = snmp.portToMacMap();
            portIpMap = snmp.portToIpMap();
            upDownMap = snmp.portsUpDownMap();
            sw.portToMac = portMacMap;
        }

        // Processing jrb databases
        Iterator<String> pdIt = portDirs.iterator();
        dp = new DataProcessor(date1, date2);
        while (pdIt.hasNext()) {
            String portdir = pdIt.next();
            String filedir = mainDir + fileSep + portdir;

            // Checking existence of each of datasources for port
            String ifInOctetsFname = filedir + fileSep + "ifInOctets.jrb";
            String ifOutOctetsFname = filedir + fileSep + "ifOutOctets.jrb";
            String ifInErrorsFname = filedir + fileSep + "ifInErrors.jrb";
            String ifOutErrorsFname = filedir + fileSep + "ifOutErrors.jrb";
            String ifInUcastpktsFname = filedir + fileSep + "ifInUcastpkts.jrb";
            String ifOutUcastPktsFname = filedir + fileSep + "ifOutUcastPkts.jrb";
            String ifInDiscardsFname = filedir + fileSep + "ifInDiscards.jrb";
            String ifOutDiscardsFname = filedir + fileSep + "ifOutDiscards.jrb";

            if (new File(ifInOctetsFname).exists())
                dp.addDatasource("ifInOctets" + portdir, ifInOctetsFname, "ifInOctets", "AVERAGE");

            if (new File(ifOutOctetsFname).exists())
                dp.addDatasource("ifOutOctets" + portdir, ifOutOctetsFname, "ifOutOctets", "AVERAGE");

            if (new File(ifInErrorsFname).exists())
                dp.addDatasource("ifInErrors" + portdir, ifInErrorsFname, "ifInErrors", "AVERAGE");
            
            if (new File(ifOutErrorsFname).exists())
                dp.addDatasource("ifOutErrors" + portdir, ifOutErrorsFname, "ifOutErrors", "AVERAGE");

            if (new File(ifInDiscardsFname).exists())
                dp.addDatasource("ifInDiscards" + portdir, ifInDiscardsFname, "ifInDiscards", "AVERAGE");

            if (new File(ifOutDiscardsFname).exists())
                dp.addDatasource("ifOutDiscards" + portdir, ifOutDiscardsFname, "ifOutDiscards", "AVERAGE");

            if (new File(ifInUcastpktsFname).exists())
                dp.addDatasource("ifInUcastpkts" + portdir, ifInUcastpktsFname, "ifInUcastpkts", "AVERAGE");
            
            if (new File(ifOutUcastPktsFname).exists())
                dp.addDatasource("ifOutUcastPkts" + portdir, ifOutUcastPktsFname, "ifOutUcastPkts", "AVERAGE");

            String stringFileName = filedir + fileSep + "strings.properties";
            File stringFile = new File(stringFileName);
            if (!stringFile.exists()) {
                System.out.println(stringFileName + " doesnt exist");
                linkSpeeds.put(portdir, "0");
                continue;
            }

            // Obtaining link speed for port
            LineNumberReader strPropReader = new LineNumberReader(new FileReader(stringFile));
            String prop = null;
            while ((prop = strPropReader.readLine()) != null) {
                if (prop.matches("^ifSpeed=\\d+$")) {
                    String[] parts = prop.split("=");
                    if (parts[1].equals("1000000000"))
                        linkSpeeds.put(portdir, "1Gb/s");
                    else if (parts[1].equals("100000000"))
                        linkSpeeds.put(portdir, "100Mb/s");
                }
            }
        }
        dp.processData();
    }

    double getIfInOctets(String portdir, String consol) {
        try {
            return dp.getAggregate("ifInOctets" + portdir, consol);
        } catch (org.jrobin.core.RrdException exc) {
            return -1;
        }
    }

    double getIfOutOctets(String portdir, String consol) {
        try {
            return dp.getAggregate("ifOutOctets" + portdir, consol);
        } catch (org.jrobin.core.RrdException exc) {
            return -1;
        }
    }

    double getIfInErrors(String portdir, String consol) {
        try {
            return dp.getAggregate("ifInErrors" + portdir, consol);
        } catch (org.jrobin.core.RrdException exc) {
            return -1;
        }
    }

    double getIfOutErrors(String portdir, String consol) {
        try {
            return dp.getAggregate("ifOutErrors" + portdir, consol);
        } catch (org.jrobin.core.RrdException exc) {
            return -1;
        }
    }

    double getInDiscards(String portdir) {
        try {
            return dp.getAggregate("ifInDiscards" + portdir, "AVERAGE");
        } catch (org.jrobin.core.RrdException exc) {
            return -1;
        }
    }

    double getOutDiscards(String portdir) {
        try {
            return dp.getAggregate("ifOutDiscards" + portdir, "AVERAGE");
        } catch (org.jrobin.core.RrdException exc) {
            return -1;
        }
    }

    double getIfInPackets(String portdir, String consol) {
        try {
            return dp.getAggregate("ifInUcastpkts" + portdir, consol);
        } catch (org.jrobin.core.RrdException exc) {
            return -1;
        }

    }

    double getIfOutPackets(String portdir, String consol) {
        try {
            return dp.getAggregate("ifOutUcastPkts" + portdir, consol);
        } catch (org.jrobin.core.RrdException exc) {
            return -1;
        }
    }

    public String getLinkSpeed(String portdir) {
        Boolean isUpObj = upDownMap.get(portdir);
        if (isUpObj != null) {
            boolean isUp = isUpObj.booleanValue();
            if (isUp)
                return linkSpeeds.get(portdir);
            else
                return "down";
        }

        return "* " + linkSpeeds.get(portdir);
    }

    public String getSnmpPortIndex(String portdir) {
        return snmpPortMap.get(portdir);
    }

    public HashSet<String> getMacMap(String portdir) {
        return portMacMap.get(portdir);
    }

    public HashSet<String> getIpMap(String portdir) {
        return portIpMap.get(portdir);
    }
}
